﻿using System;
using System.Collections.Generic;
using System.Text;
using Castle.MonoRail.Framework;
using MyMessenger.Core.Services;
using Castle.Core.Logging;
using System.Web.Security;
using MyMessenger.Core;
using System.Threading;
using System.Collections.Specialized;

namespace MyMessenger.Web.Filters
{
    public class AuthenticationFilter : Filter
    {
        private ISecurityService securityService;
        private ILogger logger = NullLogger.Instance;

        public AuthenticationFilter(ISecurityService securityService)
        {
            this.securityService = securityService;
        }

        public ILogger Logger
        {
            get { return logger; }
            set { logger = value; }
        }

        protected override bool OnBeforeAction(IRailsEngineContext context, Controller controller)
        {
            try
            {
                string cookieContent = context.Request.ReadCookie(FormsAuthentication.FormsCookieName);

                if (cookieContent == null)
                {
                    SendToLoginPage(controller);
                    return false;
                }

                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookieContent);

                // The cookie seems to expire in a few minutes.
                // if (ticket.Expired)
                // {
                // 	SendToLoginPage(controller);
                // 	return false;
                // }

                int userId = Convert.ToInt32(ticket.Name);

                User user = securityService.ReValidate(userId);
                context.CurrentUser = user;

                // So we can use principal permission
                Thread.CurrentPrincipal = user;

                controller.PropertyBag["authCookieContent"] = cookieContent;

                return true;
            }
            catch (Exception ex)
            {
                if (logger.IsErrorEnabled)
                {
                    logger.Error("Error performing token authentication", ex);
                }
            }

            SendToLoginPage(controller);
            return false;
        }

        private static void SendToLoginPage(Controller controller)
        {
            NameValueCollection dictParams = new NameValueCollection();
            dictParams["returnUrl"] = controller.Context.Request.RawUrl;
            controller.Redirect("login", "index", dictParams);
        }
    }
}
